/*
	Copyright (C) 2011 Salil Bhagurkar

	This file is part of illusion

	illusion is free software: you can redistribute it and/or modify
	it under the terms of the GNU Lesser General Public License as
	published by the Free Software Foundation, either version 3 of
	the License, or (at your option) any later version.

	illusion is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU Lesser General Public License for more details.

	You should have received a copy of the GNU Lesser General Public
	License along with illusion.
	If not, see <http://www.gnu.org/licenses/>.
*/

#include <klib/lib.h>
#include <kernel/ilapp.h>
#include <kernel/errors.h>
#include <apimod/apimod.h>
#include <kernel/vfs.h>
#include <kernel/input.h>
#include <kernel/ilapp_base.h>


static struct apimod_console *console;
static struct apimod_base *base;
static struct apimod_fs *fs;
static struct apimod_fs1 *fs1;

#define KDIV 1024
#define MDIV (KDIV * 1024)
#define GDIV (MDIV * 1024)

static void print_mem(unsigned mem)
{
	if(mem / KDIV > 0) {
		if(mem / MDIV > 0) {
			console->printf("(size %u MiB)\n", mem / MDIV);
			return;
		}
		console->printf("(size %u KiB)\n", mem / KDIV);
		return;
	}
	console->printf("(size %u B)\n", mem);
}

int ilapp_main()
{
	GETI("console", &console);
	GETI("base", &base);
	GETI("fs", &fs);
	GETI("fs1", &fs1);

	unsigned long len;
	char *args = base->get_arguments(&len);

	unsigned long dir;
	int err;

	if(args == null) {
		err = fs->open(".", STATE_READ, &dir);
		if(err != 0) {
			console->printf("Failed to open '.'");
			return 0;
		}
	} else {
		err = fs->open(args, STATE_READ, &dir);
		if(err != 0) {
			console->printf("Invalid path: %s\n", args);
			return 0;
		}
	}

	struct sys_info1 info1;
	fs->get_info1(dir, &info1);
	console->printf("Listing children of %s\n", info1.path);

	unsigned long child;
	base->try();
	err = fs->get_child(dir, &child);
	base->exit_try();
	while(!err) {
		struct sys_info info;
		fs->get_info(child, &info);
		console->printf("%s (%d children) ", info.name, info.child_count);
		print_mem(info.length);
		base->try();
		err = fs->next_child(child);
		base->exit_try();
	}

	fs->close(dir);

	return 0;
}
